package com.nlp.server.utils;

import cn.hutool.json.JSONUtil;
import com.nlp.common.core.exception.ServiceException;
import com.nlp.server.pojo.entity.ChatQueryParams;
import com.nlp.server.properties.ChatProperties;
import com.nlp.server.response.ChatResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * 大模型交互工具类
 * @author shiliuyinzhen
 */
@Component
public class ChatUtils {

    public static final Logger log = LoggerFactory.getLogger(ChatUtils.class);

    @Autowired
    private ChatProperties chatProperties;

    /**
     * 与大模型交互，发送问题得到答案
     *
     * @param chatQueryParams
     * @param sseEmitter
     * @return
     */
    public String sendQuestion(ChatQueryParams chatQueryParams, SseEmitter sseEmitter){
        //与大模型交互并返回流式结果，同时统计总的answer
        return doPostStream(getQueryURL(), chatQueryParams.toString(),sseEmitter);
    }

    /**
     * 向指定 URL 发送POST方法的请求,返回流式数据
     *
     * @param httpUrl    发送请求的 URL
     * @param param
     * @param sseEmitter
     * @return
     */
    public String doPostStream(String httpUrl, String param, SseEmitter sseEmitter) {
        HttpURLConnection connection = null;
        InputStream is = null;
        OutputStream os = null;
        BufferedReader br = null;
        // 初始化返回结果
        StringBuffer res = new StringBuffer();
        System.out.println(param);

        try {
            URL url = new URL(httpUrl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setConnectTimeout(600000);
            connection.setReadTimeout(600000);
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Accept", "text/event-stream");

            // 发送请求参数
            os = connection.getOutputStream();
            os.write(param.getBytes());

            // 读取响应数据流
            if (connection.getResponseCode() == 200) {
                is = connection.getInputStream();
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                String responseLine = null;

                // 循环逐行读取响应数据
                while ((responseLine = br.readLine()) != null) {
                    responseLine = responseLine.replaceAll("^data:", "");
                    responseLine = responseLine.replaceAll("\n$", "");
                    System.out.println("Start>" + responseLine + "<End");
                    if (responseLine.isEmpty()) continue;
                    // 将响应行解析为 JSON 对象
                    try {
                        ChatResponse chatResponse = JSONUtil.toBean(responseLine, ChatResponse.class);

                        // 检查 SseEmitter 是否已完成
                        if (sseEmitter != null) {
                            try {
                                // 发送 delta 到客户端
                                sseEmitter.send(SseEmitter.event()
                                        .id("200")
                                        .name("delta")
                                        .data(chatResponse.getAnswer()));

                                // 将每行结果拼接到总的返回结果中
                                res.append(chatResponse.getAnswer());
                            } catch (IllegalStateException e) {
                                // SseEmitter 已经完成或关闭，停止发送
                                throw new ServiceException("SseEmitter 已经关闭，停止发送数据");
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        try {
                            sseEmitter.send(SseEmitter.event()
                                    .id("500")
                                    .name("error")
                                    .data("解析响应时出错: " + e.getMessage()));
                        } catch (IOException ioException) {
                            throw new ServiceException("发送错误信息失败: " + ioException.getMessage());
                        }
                        break;
                    }
                }

                // 检查并完成 SSE 流，表示发送完成
                if (sseEmitter != null) {
                    sseEmitter.complete();
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            try {
                if (br != null) br.close();
                if (os != null) os.close();
                if (is != null) is.close();
                if (connection != null) connection.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // 返回拼接的所有结果
        return res.toString();
    }

    /**
     * 获取基本的URL
     * @return
     */
    public String getBaseURL(){
         return "http://" + chatProperties.getHost()
                    + ":" + chatProperties.getPort();
    }

    /**
     * 获取查询的URL
     * @return
     */
    public String getQueryURL() {
        return getBaseURL() + chatProperties.getQueryUrl();
    }
}
